
from pprint import pformat

from .grammar import *


def format_object(obj: object) -> str:
    return pformat(_format_object(obj))


def _format_object(obj: object) -> dict:
    if isinstance(obj, list):
        return [_format_object(x) for x in obj]

    if isinstance(obj, Rule):
        return {
            'Rule': {
                'name': obj.name,
                'alts': _format_object(obj.alts)
            }
        }
    elif isinstance(obj, Meta):
        return {
            'Meta': {
                'name': obj.meta_name,
                'content': obj.meta_content,
            }
        }

    elif isinstance(obj, Grammar):
        return {
            'Grammar': {
                'metas': _format_object(obj.metas),
                'rules': _format_object(obj.rules),
            }
        }

    elif isinstance(obj, Item0):
        return {
            'Item0': {
                'value': obj.value,
                'type': obj.item_type,
                'alias': obj.alias,
            }
        }

    elif isinstance(obj, Alternative):
        return {
            'Alternative': {
                'items': _format_object(obj.items),
                'action': _format_object(
                    obj.action.string if obj.action else 'None')
            }
        }

    elif isinstance(obj, Item):
        return {
            'Item': {
                'value': _format_object(obj.value),
                'alias': _format_object(obj.alias),
                'decoaction': _format_object(obj.director)
            }
        }

    elif isinstance(obj, Basic):
        return {
            'Basic': {
                'value': _format_object(obj.value),
                'type': _format_object(obj.type)
            }
        }

    elif isinstance(obj, Maybe):
        return {
            'Maybe': {
                'basic': _format_object(obj.basic),
            }
        }

    elif isinstance(obj, Lookahead):
        return {
            'Lookahead': {
                'basic': _format_object(obj.basic),
            }
        }

    elif isinstance(obj, Loop):
        return {
            'Loop': {
                'basic': _format_object(obj.basic),
                'min_len': obj.min_len
            }
        }

    elif isinstance(obj, Cut):
        return {
            'Cut': '~'
        }

    elif isinstance(obj, Director):
        return {
            'Decoaction': obj.string
        }

    elif isinstance(obj, Gather):
        return {
            'Gather': {
                'sep': _format_object(obj.separator),
                'basic': _format_object(obj.basic),
            }
        }

    return str(obj)
